(function(global) {

	var hasOwn = Object.prototype.hasOwnProperty;

	Object.extend = function extend(/*destination, source1[, source_2][, source_N...]*/) {
		var a = arguments;
		for (var i = 1, len = a.length, p; i < len; i++) {
			for (p in a[i]) {
				if (hasOwn.call(a[i], p)) {
					a[0][p] = a[i][p];
				}
			}
		}
		return a[0];
	};

	if (typeof Object.keys != "function") {
		Object.keys = function keys(o) {
			var vals = [], i = 0, p;
			for (p in o) {
				if (hasOwn.call(o, p)) {
					vals[i++] = o[p];
				}
			}
			return vals;
		};
	}


	Object.each = function each(object, iterator, context) {
		try {
			for (var property in object) {
				if (hasOwn.call(object, property)) {
					iterator.call(context, object[property], property, object);
				}
			}
		}
		catch (e) {
			if (e !== ProtoLove.$break) {
				throw e;
			}
		}
		return array;
	};

	Object.isArray = function isArray(o) {
		return Array.isArray(o);
	};

	if (typeof Array.isArray != "function") {
		Object.isArray = function isArray(o) {
			return (o instanceof Array) || Object.objectType(o) == 'Array';
		};
	}

	Object.objectType = function objectType(o) {
		return Object.prototype.toString.call(o)
			.match(/^\[object\s(.*)\]$/)[1] || '';
	};

	Object.isNull = function isNull(o) { return o === null; };

	Object.isUndefined = function isUndefined(o) { return typeof o == 'undefined'; };

	var types = 'String Number Boolean Function Regexp'.split(' ');
	var len = types.length;
	for (var i = 0; i < len; i++) {
		Object['is' + types[i]] = (function(type) {
			return function(o) {
				return Object.objectType(o) == type;
			};
		})(types[i]);
	}

	// create ProtoLove if not exists
	global.ProtoLove = global.ProtoLove || {};
	// export $break
	global.ProtoLove.$break = global.ProtoLove.$break || {};
	global.$break = global.$break || global.ProtoLove.$break;

	var extend = null,
		keys = null,
		each = null,
		objectType = null,
		isArray = null,
		isNull = null,
		isUndefined = null;

})(this);
